iT邦幫忙

2025 iThome 鐵人賽

0
生成式 AI

AI 情感偵測:從聲音到表情的多模態智能應用系列 第 16

【修好 LSTM forward — 從報錯到成功預測】

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20251019/20178322jsy4FmXuF4.jpg
修好 LSTM forward執行圖

“你永遠不會忘記第一次看到 NotImplementedError。”

今天的任務很簡單:
我想讓我的 LSTM 模型學會一件小事——
看到 [1,2,3,4] → 預測 [2,3,4,5]。
沒想到我卻被一句錯誤訊息卡了一整天:
NotImplementedError: Module [LSTMModel] is missing the required "forward" function

Debug 是最好的老師這次錯誤雖然只是個縮排問題,但卻讓我更理解 PyTorch 的設計邏輯:每個模型都是一個類別,而「forward()」是它的思考過程。

當我們能掌握這層抽象邏輯後,不論是要接 CNN、RNN、Transformer,都會從從容容,游刃有餘。
https://ithelp.ithome.com.tw/upload/images/20251019/20178322jJoXHYejjk.jpg

錯誤現場:NotImplementedError

我的原始程式長這樣:

class LSTMModel(nn.Module):
    def __init__(self, input_size=1, hidden_size=32, num_layers=1, output_size=1):
        super(LSTMModel, self).__init__()
        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_size, output_size)
        
        def forward(self, x):
            out, _ = self.lstm(x)
            out = self.fc(out)
            return out

看起來沒問題對吧?但 PyTorch 報錯說「我沒有 forward()」,結果真相其實非常細節:就是我把 forward() 縮排到 init 裡面去了!這代表這個函式只存在於 init 的作用域中,而不是屬於這個類別(class)的方法,對 Python 來說,這段根本就像不存在一樣。

修正後的版本:讓模型「會思考」

修正只要一行!
把 forward() 往左退一格,
init 平行就好👇

import torch
import torch.nn as nn
import torch.optim as optim

# 模型定義
class LSTMModel(nn.Module):
    def __init__(self, input_size=1, hidden_size=32, num_layers=1, output_size=1):
        super(LSTMModel, self).__init__()
        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_size, output_size)

    # ✅ 正確縮排:讓 forward 成為類別方法
    def forward(self, x):
        out, _ = self.lstm(x)
        out = self.fc(out)
        return out

小型實驗:LSTM 學會「數數」
下面是完整可執行的範例。它會讓模型從 [1,2,3,4] 學會輸出 [2,3,4,5]。

# 建立資料
x = torch.tensor([[1,2,3,4]], dtype=torch.float32).unsqueeze(-1)
y = torch.tensor([[2,3,4,5]], dtype=torch.float32).unsqueeze(-1)

# 初始化
model = LSTMModel()
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)

# 訓練
for epoch in range(200):
    optimizer.zero_grad()
    output = model(x)
    loss = criterion(output, y)
    loss.backward()
    optimizer.step()

    if (epoch+1) % 20 == 0:
        print(f"Epoch [{epoch+1}/200], Loss: {loss.item():.6f}")

# 測試
test_input = torch.tensor([[2,3,4,5]], dtype=torch.float32).unsqueeze(-1)
pred = model(test_input).detach().numpy()
print("\nInput:", test_input.view(-1).tolist())
print("Predicted:", pred.round(2).reshape(-1).tolist())

✅ 執行結果

Epoch [20/200], Loss: 0.032101
Epoch [40/200], Loss: 0.000823
...
Input: [2.0, 3.0, 4.0, 5.0]
Predicted: [3.0, 4.0, 5.0, 6.0]

模型成功學會了「加一的規律」!也代表我們的 LSTM 實作路終於跑通了恭喜賀喜!!


上一篇
【從靜態神經網路到有「記憶」的網路模型 ——讓 AI 理解時間的流動 | LSTM 時序資料入門】
下一篇
【LSTM 處理真實時序資料(sin 波案例)】
系列文
AI 情感偵測:從聲音到表情的多模態智能應用19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言